﻿// Copyright (c) 2014 Jonathan Magnan (http://jonathanmagnan.com).
// All rights reserved (http://jonathanmagnan.com/icon-library).
// Licensed under MIT License (MIT) (http://ziconlibrary.codeplex.com/license).

using System;
using System.Collections.Generic;
using System.Linq;

namespace Z
{
    /// <summary>C# object to compare list.</summary>
    /// <typeparam name="T1">The object type to compare from.</typeparam>
    /// <typeparam name="T2">The object type to compare to.</typeparam>
    public class DictionaryCompare<TKey, TValueLeft, TValueRight>
    {
        /// <summary>Item List 1.</summary>
        public IDictionary<TKey, TValueLeft> ItemList1;

        /// <summary>Item List 2.</summary>
        public IDictionary<TKey, TValueRight> ItemList2;

        /// <summary>The ListCompareResult.</summary>
        public ListCompareResult<KeyValuePair<TKey, TValueLeft>, KeyValuePair<TKey, TValueRight>> ListCompareResult = new ListCompareResult<KeyValuePair<TKey, TValueLeft>, KeyValuePair<TKey, TValueRight>>();

        /// <summary>Constructor to compare two list.</summary>
        /// <param name="itemList1">The item list 1 of T1 type.</param>
        /// <param name="itemList2">The item list 2 of T2 type.</param>
        public DictionaryCompare(IDictionary<TKey, TValueLeft> itemList1, IDictionary<TKey, TValueRight> itemList2)
        {
            ItemList1 = itemList1;
            ItemList2 = itemList2;
        }

        /// <summary>
        ///     Compare two list and return the result.
        /// </summary>
        /// <returns>The ListCompareResult.</returns>
        public ListCompareResult<KeyValuePair<TKey, TValueLeft>, KeyValuePair<TKey, TValueRight>> Compare()
        {
            // Retrieve all items which exists in both list
            ListCompareResult.ItemListEqual = ((from o1 in ItemList1
                where ItemList2.ContainsKey(o1.Key)
                select new {value = new Tuple<KeyValuePair<TKey, TValueLeft>, KeyValuePair<TKey, TValueRight>>(o1, new KeyValuePair<TKey, TValueRight>(o1.Key, ItemList2[o1.Key]))}).Select(x => x.value).ToList());

            ListCompareResult.ItemListEqualLeft = ListCompareResult.ItemListEqual.Select(x => x.Item1).ToList();
            ListCompareResult.ItemListEqualRight = ListCompareResult.ItemListEqual.Select(x => x.Item2).ToList();

            // Retrieve all items which exists only in List1
            ListCompareResult.ItemListLeft = ItemList1.Except(ListCompareResult.ItemListEqualLeft).ToList();

            // Retrieve all items which exists only in List2
            ListCompareResult.ItemListRight = ItemList2.Except(ListCompareResult.ItemListEqualRight).ToList();

            return ListCompareResult;
        }
    }
}